home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume25 / settime < prev    next >
Encoding:
Text File  |  1992-03-10  |  22.4 KB  |  766 lines

  1. Newsgroups: comp.sources.unix
  2. From: autodesk!throop!kelvin@uunet.uu.net (John Walker)
  3. Subject: v25i150: settime - Set system time from atomic clock
  4. Sender: unix-sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: autodesk!throop!kelvin@uunet.uu.net (John Walker)
  8. Posting-Number: Volume 25, Issue 150
  9. Archive-Name: settime
  10.  
  11. Whaddya expect from Switzerland?  A time setting program for Unix!
  12.  
  13.     John Walker <autodesk!throop!kelvin@uunet.uu.net>
  14.  
  15. NAME
  16.      settime - Set system time from atomic clock
  17.  
  18. SYNOPSIS
  19.      settime [ -e ]  [ -mmodem_port ]  [ -ndial_string ]  [ -ttimeout ]
  20.  
  21. DESCRIPTION
  22.      Don't you just hate it when your computer clock doesn't keep
  23.      accurate time?  Not only is a balky clock irritating, it can
  24.      lead to more serious problems such as make failing to recom-
  25.      pile  files  or files not being backed up, particularly in a
  26.      local network environment.
  27.  
  28.      For a good time, call (303) 494-4774.  It's from the govern-
  29.      ment, and it's there to help you.  The National Institute of
  30.      Standards  and  Technology,  NIST,  (formerly  the  National
  31.      Bureau  of Standards) maintains the master time standard for
  32.      the United States with a bank of  cesium  atomic  clocks  in
  33.      Boulder,  Colorado.   They  provide  a dial-up service which
  34.      furnishes a time and date directly traceable to the national
  35.      time  standard which, in turn, is based on the definition of
  36.      the second.  You don't get any more accurate than that.  The
  37.      service  is free of charge (other than the regular long dis-
  38.      tance telephone cost).
  39.  
  40. #! /bin/sh
  41. # This is a shell archive, meaning:
  42. # 1. Remove everything above the #! /bin/sh line.
  43. # 2. Save the resulting text in a file.
  44. # 3. Execute the file with /bin/sh (not csh) to create the files:
  45. #    Makefile
  46. #    settime.c
  47. #    settime.1
  48. #    settime.bat
  49. #    nettime
  50. # This archive created: Mon Aug 26 13:05:52 1991
  51. export PATH; PATH=/bin:$PATH
  52. echo shar: extracting "'Makefile'" '(295 characters)'
  53. if test -f 'Makefile'
  54. then
  55.        echo shar: will not over-write existing file "'Makefile'"
  56. else
  57. cat << \SHAR_EOF > 'Makefile'
  58.  
  59. RELFILES = Makefile settime.c settime.1 settime.bat nettime
  60.  
  61. settime:    settime.o
  62.     cc settime.o -o settime
  63.     strip settime
  64.  
  65. clean:
  66.     rm -f settime
  67.     rm -f *.bak *.o
  68.     rm -f core cscope.out
  69.  
  70. manpage:
  71.     nroff -man settime.1 | more
  72.  
  73. lint:
  74.     lint settime.c
  75.  
  76. shar:
  77.     shar -b -v $(RELFILES) >settime.shar
  78.  
  79. SHAR_EOF
  80. fi # end of overwriting check
  81. echo shar: extracting "'settime.c'" '(9771 characters)'
  82. if test -f 'settime.c'
  83. then
  84.        echo shar: will not over-write existing file "'settime.c'"
  85. else
  86. cat << \SHAR_EOF > 'settime.c'
  87. /*
  88.  
  89.     Set  UNIX  system  clock  from  the  atomic  clock at the National
  90.     Institute of Standards and Technology (NIST) in Boulder  Colorado.
  91.  
  92.     Designed and implemented in May of 1991 by John Walker.
  93.  
  94.     This  program,  which should be run when in super-user mode, dials
  95.     into the telephone time service maintained by the NIST in Boulder,
  96.     obtains  the  time    from  the  atomic  clock  there (obtaining two
  97.     consecutive valid readings to guard against communication errors),
  98.     then sets the system clock at the moment the time hack is received
  99.     for the next second.  While waiting for the tick, the program goes
  100.     into  a high-priority CPU loop waiting for the tick to be received
  101.     to obtain the best accuracy.
  102.  
  103.     The modem port, modem dial codes and telephone number, and various
  104.     other  parameters  are  set on the command line.  The defaults are
  105.     equivalent to the following:
  106.  
  107.     settime
  108.         -M/dev/cua0           -- Modem port
  109.         -NATDT13034944774          -- Dial command and phone number
  110.         -T120              -- Two minute timeout
  111.  
  112.     If you specify the "-E" option, all modem input and output will be
  113.     echoed to standard output.
  114.  
  115.     You  don't  have  to be super-user to run the progrmam, but if you
  116.     aren't the system time and date won't  be  changed,  as  only  the
  117.     super-user may change them.
  118.  
  119. */
  120.  
  121. #define REVDATE "13th May 1991"
  122.  
  123. #include <sys/types.h>
  124. #include <sys/time.h>
  125. #include <stdio.h>
  126. #include <fcntl.h>
  127. #include <termio.h>
  128. #include <time.h>
  129.  
  130. #define     FALSE   0
  131. #define     TRUE    1
  132.  
  133. #define     EOS     '\0'
  134.  
  135. struct termio newmode, oldmode;
  136.  
  137. static char *modem = "/dev/cua0";     /* Modem file name */
  138. static char *dialstring = "ATDT13034944774"; /* Dial command */
  139. static int echoin = FALSE;          /* Echo modem info if nonzero */
  140. static int port;              /* Modem file descriptor */
  141. static char line[132];              /* Input buffer */
  142. static int jdate1970 = 2440588;       /* Julian date of January 1, 1970 */
  143. static long usdelay;              /* Line delay in microseconds */
  144. static time_t bailout;              /* Time to give up if no success */
  145.  
  146. /*  TIMEDOUT  --  Check for timeout expired.  */
  147.  
  148. static int timedout()
  149. {
  150.     return time(NULL) > bailout;
  151. }
  152.  
  153. /*  MREAD  --  Read next character from modem. */
  154.  
  155. static int mread(buf)
  156.   char *buf;
  157. {
  158.     return read(port, buf, 1);
  159. }
  160.  
  161.  
  162. /*  INLINE  --    Obtain a newline terminated input line from the modem.    */
  163.  
  164. static int inline()
  165. {
  166.     int l = 0;
  167.     char buf;
  168.  
  169.     while (TRUE) {
  170.     if (mread(&buf) > 0) {
  171.         if (echoin) {
  172.         putchar(buf);
  173.         }
  174.             if (buf == '\n') {
  175.         line[l] = EOS;
  176.         break;
  177.         }
  178.             if (buf >= ' ' && l < 131) {
  179.         line[l++] = buf;
  180.         }
  181.     } else {
  182.         if (timedout()) {
  183.                 strcpy(line, "BUSY");
  184.         return FALSE;
  185.         }
  186.         usleep(4000L);
  187.     }
  188.     }
  189.     return TRUE;
  190. }
  191.  
  192. /*  JDATE  --  Convert internal GMT date and time to Julian day
  193.            and fraction.  */
  194.  
  195. static long jdate(t)
  196.   struct tm *t;
  197. {
  198.     long c, m, y;
  199.  
  200.     y = t->tm_year + 1900;
  201.     m = t->tm_mon + 1;
  202.     if (m > 2)
  203.        m = m - 3;
  204.     else {
  205.        m = m + 9;
  206.        y--;
  207.     }
  208.     c = y / 100L;           /* Compute century */
  209.     y -= 100L * c;
  210.     return t->tm_mday + (c * 146097L) / 4 + (y * 1461L) / 4 +
  211.         (m * 153L + 2) / 5 + 1721119L;
  212. }
  213.  
  214. /*  PARSE_NIST  --  Parse NIST time string into a "tm" structure.  */
  215.  
  216. static int parse_nist()
  217. {
  218.     int jd, yr, mo, da, hh, mm, ss, dst, ls, msadvw, msadvf;
  219.     char dut1[3], tname[20];
  220.     time_t gt;
  221.     struct tm t;
  222.  
  223.     if (sscanf(line, "%5d %2d-%2d-%2d %2d:%2d:%2d %2d %1d %3c %3d.%1d %s",
  224.     &jd, &yr, &mo, &da, &hh, &mm, &ss, &dst, &ls, dut1, &msadvw,
  225.     &msadvf, tname) < 13)
  226.     return 0;
  227.  
  228.     if (strncmp(tname, "UTC(NIST)", 9) != 0)
  229.     return 0;
  230.  
  231.     t.tm_sec = ss;
  232.     t.tm_min = mm;
  233.     t.tm_hour = hh;
  234.     t.tm_mday = da;
  235.     t.tm_mon = mo - 1;
  236.     t.tm_year = (yr > 90) ? yr : (yr + 100);
  237.     t.tm_isdst = (dst > 0) && (dst <= 50);
  238.     t.tm_wday = ((jd + 3) % 7);
  239.  
  240.     usdelay = ((msadvw * 10) + msadvf) * 100;
  241.  
  242.     gt = ((((jdate(&t) - jdate1970) * 24 + t.tm_hour) * 60) +
  243.         t.tm_min) * 60 + t.tm_sec;
  244.  
  245. #ifdef DEBUG
  246. { char *cp = asctime(gmtime(>));
  247. printf("Clock %d (%d) Date and time: %s Delay = %d\n", gt, time(NULL), cp,
  248.     usdelay);
  249. }
  250. #endif
  251.     return gt;
  252. }
  253.  
  254. int main(argc, argv)
  255.   int argc; char *argv[];
  256. {
  257.     int i, success;
  258.     char *cp, opt;
  259.     time_t ptime, ntime;
  260.     struct timeval tv;
  261.     int timeout = 120;              /* How long to attempt to get time */
  262.  
  263. #ifdef TEST1
  264.     strcpy(line, "48388 91-05-12 20:48:58 50 0 +.3 045.0 UTC(NIST) *");
  265.     parse_nist(&ntime);
  266.     return 0;
  267. #endif
  268.  
  269.     for (i = 1; i < argc; i++) {
  270.     cp = argv[i];
  271.         if (*cp == '-') {
  272.         opt = *(++cp);
  273.         if (islower(opt))
  274.         opt = toupper(opt);
  275.         switch (opt) {
  276.  
  277.                 case 'E':
  278.             echoin = TRUE;
  279.             break;
  280.  
  281.                 case 'M':
  282.             modem = cp + 1;
  283.             break;
  284.  
  285.                 case 'N':
  286.             dialstring = cp + 1;
  287.             break;
  288.  
  289.                 case 'T':
  290.             timeout = atoi(cp + 1);
  291.             break;
  292.  
  293.                 case '?':
  294.                 case 'U':
  295.     fprintf(stderr,"\nSETTIME  --  Set time from NIST time service.  Call");
  296.     fprintf(stderr,
  297.        "\n             with settime [options]");
  298.     fprintf(stderr,"\n");
  299.     fprintf(stderr,"\n         Options:");
  300.     fprintf(stderr,"\n           -E       Echo modem input and output");
  301.     fprintf(stderr,"\n           -Mdev    Use modem device dev");
  302.     fprintf(stderr,"\n           -Ncmd    Use cmd as modem dial command");
  303.     fprintf(stderr,"\n           -Tn      Set timeout to n seconds");
  304.     fprintf(stderr,"\n");
  305.     fprintf(stderr,"\n          (P) Throoput Ltd.  %s", REVDATE);
  306.     fprintf(stderr,"\n                All Rights Reversed");
  307.     fprintf(stderr,"\n");
  308.             return 0;
  309.         }
  310.     } else {
  311.     }
  312.     }
  313.  
  314.     if ((port = open(modem, O_RDWR | O_NDELAY)) == -1) {
  315.         fprintf(stderr, "Cannot open modem port %s\n", modem);
  316.     return 2;
  317.     }
  318.     if (ioctl(port, TCGETA, &oldmode) == -1) {       /* Get current tty mode */
  319.         perror(modem);
  320.         return 2;
  321.     }
  322.     newmode = oldmode;              /* Save it to restore port later */
  323.     bailout = time(NULL) + timeout;   /* Set time to give up */
  324.  
  325.     if (echoin) {
  326.     setbuf(stdout, NULL);          /* Make echoed output unbuffered */
  327.     }
  328.  
  329.     /* Set the modem port to the proper modes for calling the time
  330.        service. */
  331.  
  332.     newmode.c_iflag = IGNBRK | IGNPAR | ISTRIP;
  333.     newmode.c_oflag = 0;
  334.     newmode.c_cflag = B1200 | CS7 | CREAD | PARENB | HUPCL;
  335.     newmode.c_lflag = 0;
  336.     if (ioctl(port, TCSETA, &newmode) == -1) {
  337.         fprintf(stderr, "Cannot set modem to desired modes\n");
  338.         perror(modem);
  339.         return 2;
  340.     }
  341.  
  342.     /* Dial the time service. */
  343.  
  344.     if (fcntl(port, F_SETFL, FNDELAY) == -1) {
  345.         fprintf(stderr, "Cannot set port to non-delayed response\n");
  346.         perror(modem);
  347.         return 2;
  348.     }
  349.     if (write(port, "\r\r\r", 3) != 3) {
  350.         fprintf(stderr, "Error sending CR's to modem\n");
  351.         perror(modem);
  352.         return 2;
  353.     }
  354.     sleep(1);
  355.     while (read(port, &opt, 1) > 0) ; /* Flush input */
  356.     if (echoin) {
  357.         printf("%s\n", dialstring);
  358.     }
  359.     if (write(port, dialstring, strlen(dialstring)) != strlen(dialstring) ||
  360.         write(port, "\r", 1) != 1) {
  361.         fprintf(stderr, "Error sending dial string to modem\n");
  362.         perror(modem);
  363.     }
  364.  
  365.     /* Wait until we're connected.  If we get a busy signal, give up
  366.        and report an error status.  */
  367.  
  368.     while (inline()) {
  369.         if ((strncmp(line, "CONNECT", 7) == 0) || (line[0] == '5')) {
  370.         break;
  371.     }
  372.         if (strncmp(line, "BUSY", 4) == 0 ||
  373.             strncmp(line, "NO ", 3) == 0 ||
  374.             strncmp(line, "ERROR", 5) == 0 ||
  375.             line[0] == '3' || line[0] == '4' || line[0] == '6' ||
  376.             line[0] == '7' || line[0] == '8') {
  377.             fprintf(stderr, "Unable to connect.\n");
  378.         return 1;
  379.     }
  380.     }
  381.  
  382.     /*  At this point we're connected.  Ignore all data from the line
  383.     until we receive two consecutive valid time signals one second
  384.         apart.  Once we've received these two signals, prepare the
  385.     time setting for the next second and spin until we receive
  386.         the "*" that indicates the correct instant to set the clock.
  387.     At that moment, change the system clock.  */
  388.  
  389.     ptime = 0;
  390.     success = FALSE;
  391.     while (!success && !timedout() && inline()) {
  392.     if (ptime == 0) {
  393.         ptime = parse_nist();
  394.         ntime = 0;
  395.     } else if (ntime == 0) {
  396.         ntime = parse_nist();
  397.         if (ntime == (ptime + 1)) {
  398.         int rpyet = 0;
  399.  
  400.         tv.tv_sec = ntime + 1;
  401.         tv.tv_usec = 0;
  402.         while (TRUE) {
  403.             char buf;
  404.             int ticker = 0;   /* CPU loop timeout check */
  405.  
  406.             if (mread(&buf) > 0) {
  407.             if (echoin) {
  408.                 putchar(buf);
  409.             }
  410.                         if ((buf == '*') || (buf == '#')) {
  411.                 settimeofday(&tv, NULL);
  412.                 success = TRUE;
  413.                 nice(10);       /* Drop to normal priority */
  414.                 break;
  415.                         } else if (buf == ')') {
  416.                 rpyet = 1;
  417.                 nice(-10);       /* Set high priority */
  418.                         } else if (buf < ' ') {
  419.                 ptime = 0;
  420.                 if (rpyet) {
  421.                 nice(10);  /* Drop to normal priority */
  422.                 }
  423.             }
  424.             } else {
  425.             if (!rpyet) {
  426.                 usleep(2000L);
  427.                 if (timedout()) {
  428.                 break;
  429.                 }
  430.             } else {
  431.                 if (((++ticker) % 100) == 0) {
  432.                 if (timedout()) {
  433.                     break;
  434.                 }
  435.                 }
  436.             }
  437.             }
  438.         }
  439.         } else {
  440.         ptime = 0;
  441.         }
  442.     }
  443.     }
  444.  
  445.     if (echoin) {
  446.         putchar('\n');
  447.     }
  448.     if (success) {
  449.         printf("Universal time: %s", asctime(gmtime(&tv.tv_sec)));
  450.         printf("Local time:     %s", asctime(localtime(&tv.tv_sec)));
  451.     }
  452.  
  453.     /* Restore port to original modes and close, disconnecting the
  454.        modem. */
  455.  
  456.     ioctl(port, TCSETAW, &oldmode);
  457.     ioctl(port, TCFLSH, 2);
  458.     close(port);
  459.  
  460.     return 0;
  461. }
  462. SHAR_EOF
  463. fi # end of overwriting check
  464. echo shar: extracting "'settime.1'" '(9057 characters)'
  465. if test -f 'settime.1'
  466. then
  467.        echo shar: will not over-write existing file "'settime.1'"
  468. else
  469. cat << \SHAR_EOF > 'settime.1'
  470. .TH SETTIME 1 "13 MAY 1991"
  471. .UC 4
  472. .SH NAME
  473. settime \- Set system time from atomic clock
  474. .SH SYNOPSIS
  475. .B settime
  476. [
  477. .B \-e
  478. ] [
  479. .BI \-m modem_port
  480. ] [
  481. .BI \-n dial_string
  482. ] [
  483. .BI \-t timeout
  484. ]
  485. .SH DESCRIPTION
  486. Don't you just
  487. .I hate
  488. it when your computer clock doesn't keep accurate time?  Not only is
  489. a balky clock irritating, it can lead to more serious problems such as
  490. .B make
  491. failing to recompile files or files not being backed up, particularly
  492. in a local network environment.
  493. .PP
  494. For a good time, call (303) 494-4774.  It's from the government, and
  495. it's there to help you.  The National Institute of Standards and
  496. Technology, NIST, (formerly the National Bureau of Standards)
  497. maintains the master time standard for the United States with a bank
  498. of cesium atomic clocks in Boulder, Colorado.  They provide a dial-up
  499. service which furnishes a time and date directly traceable to the
  500. national time standard which, in turn, is based on the definition of
  501. the second.  You don't get any more accurate than that.  The service is
  502. free of charge (other than the regular long distance telephone cost).
  503. .PP
  504. The time and date are provided at 1200 baud, with compensation for
  505. line and modem delays.  By carefully adjusting for speed of light
  506. lag, modem character serialisation and assembly time, and computer
  507. response time, it is usually possible to obtain the time to within two
  508. milliseconds of the correct value.  In practice, it is rarely worth
  509. going to all the added difficulty since most computer clocks drift
  510. sufficiently to erase such a precision setting within a couple of
  511. hours.  A very simple time setting procedure suffices to obtain the
  512. time to within 10 or 20 milliseconds of the standard, which is usually
  513. more than adequate.
  514. .PP
  515. .I settime
  516. is a Unix program that dials the NIST time service with a Hayes-like
  517. modem, obtains the time from the standard, performing validity
  518. checking to guard against communication errors, then, if run by the
  519. super-user, sets the computer's time of day clock with the
  520. .B settimeofday(\|)
  521. call.
  522.  
  523. .SH OPTIONS
  524. .TP 10
  525. .B \-e
  526. Echo modem input and output to standard output.  This option is
  527. intended for debugging only; using it introduces delays which reduce
  528. the accuracy with with the system clock is set.
  529. .TE
  530. .TP
  531. .BI \-m modem_port
  532. Use
  533. .I modem_port
  534. to dial the NIST time service.  If omitted, the default port of
  535. .B /dev/cua0
  536. is used.
  537. .TP
  538. .BI \-n dial_string
  539. The given
  540. .I dial_string
  541. is sent to the modem to dial the NIST time service.  The string
  542. may contain all required modem commands in addition to the telephone
  543. number.  A carriage return is automatically appended to the given
  544. string.  If the option is omitted, a default dial string of
  545. .B ATDT13034944774
  546. is used.  If you require pulse dialing, a prefix to get an outside
  547. line, or special modem setup, specify an alternative dial string with
  548. the required modes.
  549. .TP
  550. .BI \-t timeout
  551. .I settime
  552. allows two minutes to obtain the time from NIST; this usually suffices
  553. and the time limit prevents running up large phone bills if NIST is
  554. out of service.  You can change the timeout, if desired, by specifying
  555. the length in seconds, with this option.
  556.  
  557. .SH BUGS
  558. The program has currently been tested only on a Sun SPARCStation 2
  559. with a Hayes Smartmodem 2400.  Although I've tried to use only the
  560. simplest and most portable facilities in this program, data
  561. communications always involves a modicum of pain when porting to a new
  562. system, and this program will probably prove no exception.  Please
  563. send me any portability or other fixes you make for your system.
  564. .PP
  565. The program could be even more careful than at present in verifying
  566. correctness of the received time and date and in checking for odd
  567. communications failures.  So far, the level of checking in the program
  568. has proven adequate.
  569. .PP
  570. If run by a user other than the super-user, no warning is given that
  571. the system time is not changed.
  572. .PP
  573. The ultra-precise mode in which the actual modem and line delay is measured
  574. by the NIST computer and compensated for is not implemented.  This
  575. mode requires instantaneous local echo-back of received characters.
  576. Unix systems cannot, in my experience,
  577. provide the consistent real-time response required by this mode.
  578. .SH SEE ALSO
  579. .BR settimeofday (2)
  580. .SH AUTHOR
  581.     John Walker
  582. .br
  583.     Autodesk SA
  584. .br
  585.     Avenue des Champs-Montants 14b
  586. .br
  587.     CH-2074 MARIN
  588. .br
  589.     Switzerland
  590. .br
  591.     Fax:    038/33 88 15
  592. .br
  593.     Voice:  038/33 76 33
  594. .br
  595.     Usenet: kelvin@Autodesk.com
  596. .SH DETAILS OF THE TIME SERVICE
  597.  
  598. .ce 2
  599. DESCRIPTION OF THE
  600. AUTOMATED COMPUTER TELEPHONE SERVICE (ACTS)
  601.  
  602.  
  603. The following is transmitted (at 1200 Baud) after completion of the
  604. telephone connection.
  605.  
  606. .nf
  607.      ? = HELP
  608.      National Institute of Standards and Technology
  609.      Telephone Time Service
  610.  
  611.                              D  L D
  612.       MJD  YR MO DA H  M  S  ST S UT1 msADV        <OTM>
  613.      47999 90-04-18 21:39:15 50 0 +.1 045.0 UTC(NIST) *
  614.      47999 90-04-18 21:39:16 50 0 +.1 045.0 UTC(NIST) *
  615.      47999 90-04-18 21:39:17 50 0 +.1 045.0 UTC(NIST) *
  616.      47999 90-04-18 21:39:18 50 0 +.1 045.0 UTC(NIST) *
  617.      47999 90-04-18 21:39:19 50 0 +.1 037.6 UTC(NIST) #
  618.      47999 90-04-18 21:39:20 50 0 +.1 037.6 UTC(NIST) #
  619.      etc..etc...etc.......
  620. .fi
  621.  
  622. UTC = Universal Time Coordinated, the official world time referred to the
  623. zero meridian.
  624. .PP
  625. DST = Daylight savings time characters, valid for the continental U.S., are
  626. set as follows:
  627.  
  628. .nf
  629.   00 = We are on standard time (ST).
  630.   50 = We are on DST.
  631.   99 to 51 = Now on ST, go to DST when your local time is
  632.              2:00 am and the count is 51.    The count is 
  633.              decremented daily at 00 (UTC).
  634.   49 to 01 = Now on DST, go to ST when your local time is
  635.              2:00 am and the count is 01.    The count is 
  636.              decremented daily at 00 (UTC).
  637. .fi
  638. .PP
  639. The two DST characters provide up to 48 days advance notice of a change in
  640. time.  The count remains at 00 or 50 at other times.
  641.  
  642. .PP
  643.  
  644. LS = Leap second flag is set to "1" to indicate that a leap second is to be
  645. added as 23:59:60 (UTC) on the last day of the current UTC month.  The LS
  646. flag will be reset to "0" starting with 23:59:60 (UTC).  The flag will
  647. remain on for the entire month before the second is added.  Leap seconds
  648. are added as needed at the end of any month.  Usually June and/or December
  649. are chosen.
  650.  
  651. .PP
  652.  
  653.  
  654. DUT1 = Approximate difference between earth rotation time (UT1) and UTC, in
  655. steps of 0.1 second.  DUT1 = UT1 - UTC
  656.  
  657. .PP
  658.  
  659. MJD = Modified Julian Date, often used to tag certain scientific data.
  660.  
  661. .PP
  662.  
  663. The full time format is sent at 1200 Baud, 8 bit, 1 stop, no parity.
  664. The format at 300 Baud is also 8 bit, 1 stop, no parity. 
  665. At 300 Baud the MJD and DUT1 values are deleted and the
  666. time is transmitted only on even seconds.
  667.  
  668. .PP
  669.  
  670. Maximum on line time will be 56 seconds.  If all lines are busy at any time,
  671. the oldest call will be terminated if it has been on line more than 28
  672. seconds, else, the call that first reaches 28 seconds will be terminated. 
  673.  
  674. .PP
  675.  
  676. Current time is valid at the "on-time" marker (OTM), either "*" or "#". 
  677. The nominal on-time marker (*) will be transmitted 45 ms early to account
  678. for the 8 ms required to send 1 character at 1200 Baud, plus an additional
  679. 7 ms for delay from NIST to the user, and approximately 30 ms "scrambler"
  680. delay inherent in 1200 Baud modems.  If the caller echoes all characters,
  681. NIST will measure the round trip delay and advance the on-time marker so
  682. that the midpoint of the stop bit arrives at the user on time.  The amount
  683. of msADV will reflect the actual required advance in milliseconds and the
  684. OTM will be a "#".  The NIST system requires 4 or 5 consecutive delay
  685. measurements which are consistent before switching from "*" to "#".
  686. If the user has a 1200 Baud modem with the same internal delay as that used
  687. by NIST, then the "#" OTM should arrive at the user within +-2 ms of the
  688. correct time.  However, NIST has studied different brands of 1200 Baud
  689. modems and found internal delays from 24 ms to 40 ms and offsets of the
  690. "#" OTM of +-10 ms.  For many computer users, +-10 ms accuracy should be
  691. more than adequate since many computer internal clocks can only be set with
  692. granularity of 20 to 50 ms.  In any case, the repeatability of the offset
  693. for the "#" OTM should be within +-2 ms, if the dial-up path is reciprocal
  694. and the user doesn't change the brand or model of modem used. This should
  695. be true even if the dial-up path on one day is a land-line of less than
  696. 40 ms (one way) and on the next day is a satellite link of 260 to 300 ms.
  697. In the rare event that the path is one way by satellite and the other way
  698. by land line with a round trip measurement in the range of 90 to 260 ms,
  699. the OTM will remain a "*" indicating 45 ms advance.
  700.  
  701. .PP
  702.  
  703. For user comments write:
  704.  
  705. .nf
  706. NIST-ACTS
  707. Time and Frequency Division
  708. Mail Stop 524
  709. 325 Broadway
  710. Boulder, CO  80303
  711. USA
  712. .fi
  713.  
  714. Software for setting (PC)DOS compatable machines is available
  715. on a 360-kbyte diskette for $35.00 from:
  716. .PP
  717. NIST Office of Standard Reference Materials
  718. B311-Chemistry Bldg, NIST, Gaithersburg, MD, 20899, USA, (301) 975-6776
  719. SHAR_EOF
  720. fi # end of overwriting check
  721. echo shar: extracting "'settime.bat'" '(409 characters)'
  722. if test -f 'settime.bat'
  723. then
  724.        echo shar: will not over-write existing file "'settime.bat'"
  725. else
  726. cat << \SHAR_EOF > 'settime.bat'
  727. rem
  728. rem     Set the DOS time, date, and time zone from a master
  729. rem     time kept on a Unix system via NFS.
  730. rem
  731. rem     Usage:
  732. rem             settime time_server_host
  733. rem
  734. rsh %1 date +\"time %%T\" >zztime.bat
  735. rsh %1 date +\"date %%D\" >>zztime.bat
  736. rsh %1 "date|cut -d' ' -f5-|awk '{ ORS=\"\";print \"set tz=\" $1;if(NF>2) print \" \" $2;print \"\n\"}'">>zztime.bat
  737. call zztime.bat
  738. del zztime.bat
  739. SHAR_EOF
  740. chmod +x 'settime.bat'
  741. fi # end of overwriting check
  742. echo shar: extracting "'nettime'" '(257 characters)'
  743. if test -f 'nettime'
  744. then
  745.        echo shar: will not over-write existing file "'nettime'"
  746. else
  747. cat << \SHAR_EOF > 'nettime'
  748. #! /bin/sh
  749. #
  750. #       Set time from network time server machine given as
  751. #       first argument.  You must be the super-user for the
  752. #       time to be set.
  753. #
  754. #       Example:
  755. #                   nettime worldbrain
  756. #
  757. rsh $1 date +\"date %y%m%d%H%M.%S\" | sh
  758. SHAR_EOF
  759. chmod +x 'nettime'
  760. fi # end of overwriting check
  761. #    End of shell archive
  762. exit 0
  763. ----------------------------- End source ---------------------- settime.shar
  764.  
  765.  
  766.